import pygame
import random
import sys
import math
import os

# 初始化 Pygame
pygame.init()

# 定义颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
DARK_GREEN = (0, 200, 0)
LIGHT_GREEN = (0, 255, 100)
YELLOW = (255, 255, 0)

# 定义方向
UP = 'UP'
DOWN = 'DOWN'
LEFT = 'LEFT'
RIGHT = 'RIGHT'

# 设置游戏窗口
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
BLOCK_SIZE = 20
GAME_SPEED = 8  # 降低游戏速度，原来是15

# 设置中文字体
try:
    # 尝试使用系统自带的中文字体
    FONT = pygame.font.Font("C:/Windows/Fonts/msyh.ttc", 18)  # 微软雅黑
except:
    try:
        FONT = pygame.font.Font("C:/Windows/Fonts/simhei.ttf", 18)  # 黑体
    except:
        # 如果找不到中文字体，就使用系统默认字体
        FONT = pygame.font.Font(None, 18)

# 创建游戏窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('贪吃蛇游戏')

# 在加载图片资源时添加图片处理函数
def load_and_process_image(path, size=BLOCK_SIZE):
    """加载并处理图片：调整大小，设置透明度等等"""
    try:
        image = pygame.image.load(path).convert_alpha()  # 使用convert_alpha支持透明度
        return pygame.transform.scale(image, (size, size))
    except:
        return None

# 修改图片加载部分
try:
    SNAKE_HEAD = {
        'UP': load_and_process_image('assets/snake_head_up.png'),
        'DOWN': load_and_process_image('assets/snake_head_down.png'),
        'LEFT': load_and_process_image('assets/snake_head_left.png'),
        'RIGHT': load_and_process_image('assets/snake_head_right.png')
    }
    SNAKE_BODY = load_and_process_image('assets/snake_body.png')
    SNAKE_TAIL = load_and_process_image('assets/snake_tail.png')
    FOODS = [load_and_process_image(f'assets/food_{name}.png') for name in 
             ['cake', 'donut', 'ice_cream', 'cookie']]
    USE_IMAGES = all([img is not None for img in SNAKE_HEAD.values()] + 
                    [SNAKE_BODY, SNAKE_TAIL] + FOODS)
except:
    print("无法加载图片资源，将使用简单图形代替")
    USE_IMAGES = False

# 在图片加载之前添加这个函数来生成简单的图片
def generate_default_images():
    """生成默认的图片资源"""
    # 创建 assets 文件夹
    if not os.path.exists('assets'):
        os.makedirs('assets')
    
    # 生成简单的图片
    for direction in ['up', 'down', 'left', 'right']:
        surface = pygame.Surface((32, 32), pygame.SRCALPHA)
        pygame.draw.circle(surface, GREEN, (16, 16), 14)
        # 添加眼睛
        pygame.draw.circle(surface, WHITE, (20, 12), 4)
        pygame.draw.circle(surface, WHITE, (20, 20), 4)
        # 根据方向旋转
        if direction == 'up':
            surface = pygame.transform.rotate(surface, 90)
        elif direction == 'down':
            surface = pygame.transform.rotate(surface, -90)
        elif direction == 'left':
            surface = pygame.transform.rotate(surface, 180)
        pygame.image.save(surface, f'assets/snake_head_{direction}.png')
    
    # 生成身体
    surface = pygame.Surface((32, 32), pygame.SRCALPHA)
    pygame.draw.circle(surface, GREEN, (16, 16), 12)
    pygame.image.save(surface, 'assets/snake_body.png')
    
    # 生成尾部
    surface = pygame.Surface((32, 32), pygame.SRCALPHA)
    pygame.draw.circle(surface, GREEN, (16, 16), 10)
    pygame.image.save(surface, 'assets/snake_tail.png')
    
    # 生成食物
    foods = {
        'cake': (255, 192, 203),    # 粉色
        'cookie': (139, 69, 19),    # 棕色
        'donut': (255, 182, 193),   # 浅粉色
        'ice_cream': (240, 248, 255) # 白色
    }
    
    for name, color in foods.items():
        surface = pygame.Surface((32, 32), pygame.SRCALPHA)
        pygame.draw.circle(surface, color, (16, 16), 12)
        pygame.draw.circle(surface, (255, 255, 255, 128), (20, 12), 4)  # 高光
        pygame.image.save(surface, f'assets/food_{name}.png')

# 在加载图片之前调用这个函数
try:
    generate_default_images()
except:
    print("无法生成默认图片")

# 蛇类
class Snake:
    def __init__(self):
        self.length = 1
        self.positions = [(WINDOW_WIDTH//2, WINDOW_HEIGHT//2)]
        self.direction = random.choice([UP, DOWN, LEFT, RIGHT])
        self.head_color = LIGHT_GREEN
        self.body_color = GREEN
        self.tail_color = DARK_GREEN
        self.eye_color = BLACK
        self.eye_shine_color = WHITE
        self.score = 0
        self.high_score = 0  # 添加最高分属性
        self.paused = False  # 添加暂停状态标志
        self.body_rotation = 0  # 用于身体部分的旋转动画
        self.animation_state = 0
        self.pulse_counter = 0
        self.rainbow_offset = 0

    def get_head_position(self):
        return self.positions[0]

    def get_direction_tuple(self):
        """将方向字符串转换为坐标元组"""
        if self.direction == UP:
            return (0, -1)
        elif self.direction == DOWN:
            return (0, 1)
        elif self.direction == LEFT:
            return (-1, 0)
        else:  # RIGHT
            return (1, 0)

    def update(self):
        cur = self.get_head_position()
        x, y = self.get_direction_tuple()
        new = (cur[0] + (x*BLOCK_SIZE), cur[1] + (y*BLOCK_SIZE))
        
        # 检查是否撞到边界
        if (new[0] < 0 or new[0] >= WINDOW_WIDTH or 
            new[1] < 0 or new[1] >= WINDOW_HEIGHT):
            return False
            
        if new in self.positions[3:]:
            return False
        self.positions.insert(0, new)
        if len(self.positions) > self.length:
            self.positions.pop()
        return True

    def reset(self):
        self.length = 1
        self.positions = [(WINDOW_WIDTH//2, WINDOW_HEIGHT//2)]
        self.direction = random.choice([UP, DOWN, LEFT, RIGHT])
        # 更新最高分
        if self.score > self.high_score:
            self.high_score = self.score
        self.score = 0

    def render(self):
        # 更新动画状态
        self.animation_state = (self.animation_state + 0.2) % 360
        self.pulse_counter = (self.pulse_counter + 0.1) % (2 * math.pi)
        self.rainbow_offset = (self.rainbow_offset + 1) % 360
        
        for i, p in enumerate(self.positions):
            if USE_IMAGES:
                if i == 0:  # 蛇头
                    # 添加呼吸效果
                    scale_factor = 1.0 + math.sin(self.pulse_counter) * 0.1
                    size = int(BLOCK_SIZE * scale_factor)
                    head_image = SNAKE_HEAD[self.direction]
                    scaled_head = pygame.transform.scale(head_image, (size, size))
                    # 居中绘制
                    offset = (size - BLOCK_SIZE) // 2
                    screen.blit(scaled_head, (p[0] - offset, p[1] - offset))
                    
                elif i == len(self.positions) - 1:  # 蛇尾
                    scaled_tail = pygame.transform.scale(SNAKE_TAIL, (BLOCK_SIZE, BLOCK_SIZE))
                    # 根据移动方向旋转尾部
                    direction_to_prev = (
                        self.positions[-2][0] - p[0],
                        self.positions[-2][1] - p[1]
                    )
                    angle = math.degrees(math.atan2(direction_to_prev[1], direction_to_prev[0]))
                    # 添加摆动效果
                    angle += math.sin(self.animation_state * 0.1) * 10
                    rotated_tail = pygame.transform.rotate(scaled_tail, angle - 90)
                    screen.blit(rotated_tail, p)
                else:  # 蛇身
                    scaled_body = pygame.transform.scale(SNAKE_BODY, (BLOCK_SIZE, BLOCK_SIZE))
                    # 计算身体部分的旋转角度
                    prev_pos = self.positions[i-1]
                    next_pos = self.positions[i+1]
                    direction = (
                        next_pos[0] - prev_pos[0],
                        next_pos[1] - prev_pos[1]
                    )
                    angle = math.degrees(math.atan2(direction[1], direction[0]))
                    rotated_body = pygame.transform.rotate(scaled_body, angle - 90)
                    # 添加波浪效果
                    offset = math.sin(self.animation_state * 0.1 + i * 0.5) * 3
                    screen.blit(rotated_body, (p[0], p[1] + offset))
            else:
                # 非图片模式下的彩虹效果
                hue = (self.rainbow_offset + i * 30) % 360
                color = pygame.Color(0)
                color.hsva = (hue, 80, 90, 100)
                
                if i == 0:  # 蛇头
                    size = int(BLOCK_SIZE * (1.0 + math.sin(self.pulse_counter) * 0.1))
                    offset = (size - BLOCK_SIZE) // 2
                    pygame.draw.rect(screen, color, 
                                   (p[0] - offset, p[1] - offset, size, size))
                    
                    # 根据方向绘制眼睛
                    eye_size = BLOCK_SIZE // 4
                    shine_size = eye_size // 2
                    
                    # 计算眼睛位置（根据方向）
                    direction_tuple = self.get_direction_tuple()
                    if direction_tuple == (1, 0):  # RIGHT
                        eye_pos1 = (p[0] + BLOCK_SIZE - eye_size - 2, p[1] + eye_size)
                        eye_pos2 = (p[0] + BLOCK_SIZE - eye_size - 2, p[1] + BLOCK_SIZE - eye_size * 2)
                        shine_offset = (eye_size - shine_size - 1, 1)
                    elif direction_tuple == (-1, 0):  # LEFT
                        eye_pos1 = (p[0] + 2, p[1] + eye_size)
                        eye_pos2 = (p[0] + 2, p[1] + BLOCK_SIZE - eye_size * 2)
                        shine_offset = (1, 1)
                    elif direction_tuple == (0, -1):  # UP
                        eye_pos1 = (p[0] + eye_size, p[1] + 2)
                        eye_pos2 = (p[0] + BLOCK_SIZE - eye_size * 2, p[1] + 2)
                        shine_offset = (1, 1)
                    else:  # DOWN
                        eye_pos1 = (p[0] + eye_size, p[1] + BLOCK_SIZE - eye_size - 2)
                        eye_pos2 = (p[0] + BLOCK_SIZE - eye_size * 2, p[1] + BLOCK_SIZE - eye_size - 2)
                        shine_offset = (1, eye_size - shine_size - 1)
                    
                    # 绘制眼睛
                    pygame.draw.rect(screen, self.eye_color, (eye_pos1[0], eye_pos1[1], eye_size, eye_size))
                    pygame.draw.rect(screen, self.eye_color, (eye_pos2[0], eye_pos2[1], eye_size, eye_size))
                    
                    # 绘制眼睛高光
                    pygame.draw.rect(screen, self.eye_shine_color, 
                                   (eye_pos1[0] + shine_offset[0], 
                                    eye_pos1[1] + shine_offset[1], 
                                    shine_size, shine_size))
                    pygame.draw.rect(screen, self.eye_shine_color, 
                                   (eye_pos2[0] + shine_offset[0], 
                                    eye_pos2[1] + shine_offset[1], 
                                    shine_size, shine_size))
                elif i == len(self.positions) - 1:  # 蛇尾
                    color = self.tail_color
                    pygame.draw.rect(screen, color, (p[0], p[1], BLOCK_SIZE, BLOCK_SIZE))
                else:  # 蛇身
                    color = self.body_color
                    pygame.draw.rect(screen, color, (p[0], p[1], BLOCK_SIZE, BLOCK_SIZE))
                    # 添加身体关节效果
                    joint_size = BLOCK_SIZE // 5
                    pygame.draw.rect(screen, self.head_color, 
                                   (p[0] + joint_size, p[1] + joint_size, 
                                    BLOCK_SIZE - 2*joint_size, BLOCK_SIZE - 2*joint_size))

# 食物类
class Food:
    def __init__(self):
        self.position = (0, 0)
        self.color = RED
        self.shine_color = YELLOW
        if USE_IMAGES:
            self.current_food = random.choice(FOODS)
        self.randomize_position()
        self.animation_counter = 0
        self.rotation = 0
        self.scale = 1.0

    def randomize_position(self):
        if USE_IMAGES:
            self.current_food = random.choice(FOODS)
        self.position = (random.randint(0, (WINDOW_WIDTH-BLOCK_SIZE)//BLOCK_SIZE) * BLOCK_SIZE,
                        random.randint(0, (WINDOW_HEIGHT-BLOCK_SIZE)//BLOCK_SIZE) * BLOCK_SIZE)

    def render(self):
        x, y = self.position
        if USE_IMAGES:
            # 组合多个动画效果
            # 1. 上下浮动
            self.animation_counter = (self.animation_counter + 0.1) % (2 * math.pi)
            offset_y = int(math.sin(self.animation_counter) * 3)
            
            # 2. 旋转效果
            self.rotation = (self.rotation + 2) % 360
            
            # 3. 缩放效果
            self.scale = 1.0 + math.sin(self.animation_counter * 2) * 0.1
            
            size = int(BLOCK_SIZE * self.scale)
            scaled_food = pygame.transform.scale(self.current_food, (size, size))
            rotated_food = pygame.transform.rotate(scaled_food, self.rotation)
            
            # 居中绘制
            offset = (size - BLOCK_SIZE) // 2
            screen.blit(rotated_food, 
                       (x - offset, y - offset + offset_y))
            
            # 4. 添加光晕效果
            glow_surface = pygame.Surface((size + 10, size + 10), pygame.SRCALPHA)
            glow_color = (*self.color, 128)  # 半透明的光晕
            pygame.draw.circle(glow_surface, glow_color, 
                             (size // 2 + 5, size // 2 + 5), size // 2 + 5)
            screen.blit(glow_surface, (x - offset - 5, y - offset - 5 + offset_y))
        else:
            # 使用原来的方块样式
            pygame.draw.rect(screen, self.color, (x, y, BLOCK_SIZE, BLOCK_SIZE))
            shine_size = BLOCK_SIZE // 3
            pygame.draw.rect(screen, self.shine_color, (x + 2, y + 2, shine_size, shine_size))

def main():
    clock = pygame.time.Clock()
    snake = Snake()
    food = Food()
    
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    snake.paused = not snake.paused
                if not snake.paused:
                    if event.key == pygame.K_UP and snake.direction != DOWN:
                        snake.direction = UP
                    elif event.key == pygame.K_DOWN and snake.direction != UP:
                        snake.direction = DOWN
                    elif event.key == pygame.K_LEFT and snake.direction != RIGHT:
                        snake.direction = LEFT
                    elif event.key == pygame.K_RIGHT and snake.direction != LEFT:
                        snake.direction = RIGHT

        if not snake.paused:  # 只有在非暂停状态才更新游戏状态
            # 更新蛇的位置
            if not snake.update():
                snake.reset()
                food.randomize_position()

            # 检查是否吃到食物
            if snake.get_head_position() == food.position:
                snake.length += 1
                snake.score += 1
                food.randomize_position()

        # 绘制
        screen.fill(BLACK)
        snake.render()
        food.render()
        
        # 显示当前分数和最高分
        score_text = FONT.render(f'当前得分: {snake.score}', True, WHITE)
        high_score_text = FONT.render(f'最高分: {snake.high_score}', True, WHITE)
        screen.blit(score_text, (10, 10))
        screen.blit(high_score_text, (10, 50))
        
        # 如果游戏暂停，显示暂停文本
        if snake.paused:
            pause_text = FONT.render('游戏暂停 - 按空格键继续', True, WHITE)
            text_rect = pause_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2))
            # 绘制半透明背景
            s = pygame.Surface((pause_text.get_width() + 20, pause_text.get_height() + 20))
            s.fill(BLACK)
            s.set_alpha(128)
            screen.blit(s, (text_rect.x - 10, text_rect.y - 10))
            # 绘制文本
            screen.blit(pause_text, text_rect)
        
        pygame.display.update()
        clock.tick(GAME_SPEED)

if __name__ == '__main__':
    main() 